﻿#ifndef __RYN_PROTOCOL__H__
#define __RYN_PROTOCOL__H__

#ifdef __cplusplus
extern "C" {
#endif

#ifdef WIN32
#define UTF_GBK						0x40 /** GBK编码 **/
#else
#define UTF_GBK						0x00 /** UTF8编码 **/
#endif

#define PRO_P2P_TCP					0	
#define PRO_P2P_UDP					1	
#define ERRCODE_READ_TIMEOUT	    1000 /** 错误码 1000表示等待读超时	**/
#define ERRCODE_OK					1100 /** 错误码 1100表示成功 		**/
#define ERRCODE_AUTHSUCC			1200 /** 错误码 1200表示授权成功 		**/
#define ERRCODE_AUTHFAIL			1201 /** 错误码 1201表示授权失败 		**/
#define ERRCODE_SIDTMOUT			1202 /** 错误码 1202表示SID过期失效 	**/
#define ERRCODE_SCKCLOSE			1203 /** 错误码 1203表示SOCKET意外关闭，需要重新连接  **/
#define ERRCODE_SCKEXIT				1208 /** 错误码 1208表示SOCKET意外退出，需要重新连接  **/
#define ERRCODE_SHBOK 				1204 /** 错误码 1204表示心跳正常，状态已更新  **/
#define ERRCODE_SHBMUL				1205 /** 错误码 1205表示SID多处登录 ,需要重新连接授权 **/
#define ERRCODE_SCMOK				1206 /** 错误码 1206表示执行SCM成功 	**/
#define ERRCODE_SCMFAIL				1207 /** 错误码 1207表示执行SCM失败 ,需要重新连接授权 **/
#define SACCOUNT_INIT				20;	 /** 心跳计数 20 				**/
										 
										 
#define TOS_1000					0x08 /** 最小延迟 		**/
#define TOS_0100					0x04 /** 最大吞吐量		**/
#define TOS_0010					0x02 /** 最大可靠性 		**/
#define TOS_0101					0x01 /** 最小货币成本 	**/
#define TOS_0000					0x00 /** 正常服务 		**/
										 
#define SIGN_010					0x02 /** 3位标识  不对数据进行分片  并且该数据包是最后分片  	**/
#define SIGN_000					0x00 /** 3位标识  对数据进行分片 并且该数据包是最后分片 		**/
#define SIGN_001					0x01 /** 3位标识  对数据进行分片  并且该数据包不是最后分片	**/
										 
										 
#define TTL_255						0xFF /** 8位生存时间 **/
#define PTO_LUT			  (UTF_GBK|0x01) /** 8位协议  LUT协议 **/
										 
#define SAC_SHB						0x00 /** 发送心跳包					**/
#define SAC_SHB_TIMEOUT				0x70 /** 超时心跳包					**/
#define SAC_SYN						0x01 /** 发送握手包					**/
#define SAC_SAU						0x02 /** 发送授权包					**/
#define SAC_SCM						0x04 /** 发送指令包					**/
#define SAC_SDA						0x08 /** 发送数据包					**/
#define SAC_RUT						0x0A /** 返回数据包					**/
#define SAC_SNU						0x0C /** 发送免授权数据包(短连接)		**/
#define SAC_SNB						0x0E /** 发送免授权数据包(长连接)		**/
#define SAC_RCA						0x10 /** 微信扫描结果数据包			**/
#define SAC_STX						0x12 /** 发送返回纯文本指令包			**/
#define SAC_SDG						0x13 /** 打洞指令数据包(长连接)		**/
#define SAC_SDI						0x15 /** 打洞指令数据包(短连接)		**/
#define SAC_RDG						0x14 /** 返回通知A打洞数据包			**/
#define SAC_IM						0x16 /** 返回IM推送数据包			**/

#define SAC_SCM_NEWSOCKET				"NewSocket"					/** 建立指定新连接				**/
#define SAC_SCM_GETUSERPORTLIST			"GetUserPortList"			/** 获取UserPort列表			**/
#define SAC_SCM_GetCoreDataAddr			"GetCoreDataAddr"			/** 获取CoreData地址			**/
#define SAC_SCM_GetPayAccount			"GetPayAccount"				/** 获取余额					**/
#define SAC_SCM_GetOneUserPortPay		"GetOneUserPortPay"			/** 获取单价					**/
#define SAC_SCM_GetUserPortByUserAgent	"GetUserPortByUserAgent"	/** 获取UserPort By UserAgent	**/
#define SAC_SCM_GetUserPortByUserName	"GetUserPortByUserName"		/** 获取UserPort By UserName	**/
#define SAC_SCM_GetDigHoleList			"GetDigHoleList"			/** 获取DigHole列表				**/
#define SAC_SCM_NotifyADigHole			"NotifyADigHole"			/** 通知A打洞					**/
#define SAC_SCM_DynamicWconn			"DynamicWconn"				/** 动态端口映射					**/
#define SAC_SCM_GetFamilyUserList		"GetFamilyUserList"			/** 获取聊天用户列表			**/
#define SAC_SCM_IMsgTxt					"IMsgTxt"					/** 发送即时文本消息				**/

#define SAC_SNU_GetP2PSvrAddr			"GetP2PSvrAddr"				/** 获取P2PSvr地址				**/
#define SAC_SNU_GetBarCodeImg			"GetBarCodeImg"				/** 获取二维码地址(短连接)		**/
#define SAC_SNU_SocketClose				"SocketClose"				/** 友好关闭Socket				**/
#define SAC_SNU_GetUserRouteHostPort	"GetUserRouteHostPort"		/** 获取RouteHostPort		**/
#define SAC_SNU_CheckLoginNameAndPasss	"CheckLoginNameAndPasss"	/** 验证账号密码			**/

#define SAC_SNB_GetBarCodeImg			"GetSNBBarCodeImg"			/** 获取二维码地址(长连接)		**/

#define SAC_SDG_DigNatHole				"DigNatHole"				/** 往服务器方向打NAT洞			**/
#define SAC_SDG_NatADigHole				"NatADigHole"				/** 客户端A往服务器方向打NAT洞	**/
#define SAC_SDG_DigSocketClose			"DigSocketClose"			/** 关闭DigHole					**/
#define SAC_SDG_NotifyAConnectB			"NotifyAConnectB"			/** 通知A端连接BNat				**/

#define P2P_HEAD_LEN				8	/** 数据包协议头长度					**/
#define Config_Aes_IV_03			{0x54,0xE0,0xCA,0xA4,0xFB,0x78,0x3C,0x66,0x18,0x91,0x7F,0xE7,0x4A,0x00,0xD7,0xF1}	
#define CHANNEL_BEGIN 901		//通道号开始索引

#define ShowSecurityData			0

//Readµ»¥˝ ±º‰£®–ƒÃ¯œﬂ≥Ã£©µ•Œª∫¡√Î
#define SHB_READ_TIME				8000

//P2P µ»¥˝ ±º‰£®–ƒÃ¯œﬂ≥Ã£©µ•Œª∫¡√Î
#define P2P_READ_TIME				300

//Readµ»¥˝ ±º‰£®UDPœﬂ≥Ã£©µ•Œª∫¡√Î
#define SDG_READ_TIME				3000

//Readµ»¥˝ ±º‰£®÷∏¡Óœﬂ≥Ã£©µ•Œª∫¡√Î
#define SCM_READ_TIME				6000

//Scanµ»¥˝ ±º‰£®…®√Ëœﬂ≥Ã£©µ•Œª√Î
#define SCAN_WAIT_TIME				120

//Wait–ƒÃ¯º∆ ˝∆˜º∆¡ø(¥Œ)
#define SHB_MANAGER_COUNTER			12

//P2P  ˝æ›ΩªªªBuffer ¥Û–°
#define P2P_BUF_SIZE				1024 * 32

#define RTJsonLen					2048

#define FMT_ErrorCode "{\"errorCode\":%d, \"errorMsg\":\"%s\"}"

	typedef unsigned char Bit8;
	typedef unsigned short Bit16;
	typedef int Bit32;

	typedef struct P2PPackage{
		Bit8 * package;
		int packageLen;
	}P2PPackage_t;
	typedef struct ProtocolHead
	{
		Bit8 version;
		Bit8 tos;
		Bit16 total;
		Bit16 serial;
		Bit16 sign;
		Bit8 ttl;
		Bit8 pto;
		Bit16 cksum;
		Bit32 saddr;
		Bit32 sac;
	} ProtocolHead_t;


	typedef struct SecurityKey
	{
		int SecurityKeyLen;
		unsigned char * pSecurityKeyData;
	}SecurityKey_t;

	typedef struct Signature
	{
		int SignatureLen;
		unsigned char * pSignatureData;
	} Signature_t;

	typedef struct BodyData
	{
		int BodyDataLen;
		unsigned char * pBodyDData;
	} BodyData_t;

	typedef struct LutPackage
	{
		int _LutPackageLen;
		Bit8 * _LutPackage;
	} LutPackage_t;


	typedef struct SacSHBSocket{
		int sockfd;
		Bit8 * szSessionID;
	} SacSHBSocket_t;

	typedef struct SacSCMSocket{
		int sockfd;
		Bit8 * szJson;
	} SacSCMSocket_t;



typedef struct ApproxyCfgST{
char android_home_path[256];
char android_profile_path[256];
char approxy_db_file[256];
char approxy_db_table[256];
char db_sipua[256];
char db_approxyua[256];
char serialno[128];
    char daemon[1];
    char loginName[64];
    char loginPass[64];
    char isAlive[1];
    int isAutoLogin;
int valset;
unsigned int nGlTransmills			;//= 0;
		unsigned int nWorkThreadWatchDog	;//= RYN_WorkThreadWatchDogMin;
		int switch_running;
}ApproxyCfgST_t;

typedef struct ServerST{
		char serverIP[24];
		int serverPort;
	} ServerST_t;

typedef struct Approxy4cST
	{
		int channelID						;// = 0
		// 全局变量
		char gl_uidSTR[48]					;// = {0};
		char gl_sidSTR[64]					;// = {0};
		char gl_loginName[64]				;
		char gl_accessTokenSTR[256]			;
		char gl_webCtxPathSTR[256]			;
		unsigned char *pGlHbPkg				;
		unsigned int  nGlHbPkgLen			;// = 0;

		ServerST_t *pServerSTArray[64]		;//= {NULL};
		int nServerSTArraySize				;//= 0;
		char *pGlUserName					;//= NULL;
		int   nGlUserNameLen				;//	= 0;
		char *pGlPaasword					;//= NULL;
		int   nGlPaaswordLen				;//= 0;
		unsigned char *pGlSvrHost			;//= NULL;
		int  nGlSvrHostLen					;//= 0;
		int  nGlSvrPort						;//= 0;

		unsigned char glLoopServiceAddr[64] ;//= {0};//当前连接的域名地址和端口

		int watchDogloop					;//= WATCHDOG_INIT;
		int nUserRunningSta					;//= USER_RUNNING_STA_Y;
		unsigned char pGlHbSeKey[128]		;//= {0};
		int nGlConnected					;//= LUT_DISCONNECTED;
		char * pGlCoreDataAddrHost			;//= NULL;
		int	  nGlCoreDataAddrHostLen		;//= 0;
		int	  nGlCoreDataAddrPort			;//= 0;
		int	  nScanWaitSta					;//= SCAN_WAITNONE;
		char * pGlP2PServerAddrHost			;//= NULL;
		int	  nGlP2PServerAddrHostLen		;//= 0;
		int	  nGlP2PServerAddrPort			;//= 0;
		int	  nGlSvrSockfd					;//= -1;
		int stayRun							;
		unsigned int nUserLoginStatus		;//= RYN_LOGIN_STA_NONE;
	}Approxy4cST_t;


	/** 协议头字节码转协议头结构体（前提：已经验证过校验和） **/
	int NewLutProtocolHead(ProtocolHead_t *_protocolHead,Bit8 * _Buf,int nBufLen);
	/** 生成握手数据包 **/
	int NewLutSacSYNPackage(LutPackage_t *_LutPackage);
	/** 生成授权数据包 **/
	int NewLutSacSAUPackage(LutPackage_t *_LutPackage,Bit8 * szUserName,Bit8 * szPassword,Bit8 *synCode);
	/** 生成心跳数据包 **/
	int NewLutSacSHBPackage(LutPackage_t *_LutPackage,Bit8 * szSessionID);
	/** 生成指令数据包 **/
	int NewLutSacSCMPackage(LutPackage_t *_LutPackage,Bit8 * szSCM,Bit8 * szSCMDA,Bit8 * szSessionID);
	/** 生成协议数据包 **/
	int NewLutPackage(LutPackage_t *_LutPackage,Bit32 sac,Bit32 saddr,Bit16 dataSerial,char *data,int dataLen);
	/** 生成免授权指令包(短连接) **/
	int NewLutSacSNUPackage(LutPackage_t *_LutPackage,Bit8 * szSNU,Bit8 * szSNUDA);
	/** 生成免授权指令包(长连接) **/
	int NewLutSacSNBPackage(LutPackage_t *_LutPackage,Bit8 * szSNB,Bit8 * szSNBDA);
	/** 生成打洞指令包 **/
	int NewLutSacSDGPackage(LutPackage_t *_LutPackage,Bit8 * szDIG,Bit8 * szDIGDA);
	/** 生成即时消息数据包 **/
	int NewLutSacMSGPackage(LutPackage_t *_LutPackage,Bit8 * szMSG,Bit8 * szMSGDA,Bit8 * szSessionID);

	/** 生成P2P协议数据包头 **/
	int NewP2PHead(char * _head,int nP2c,int nDataLen);
	/** 生成P2P数据包 **/
	int NewP2PPackage(P2PPackage_t * _p2pPackage,char * _head,Bit8 * szData);
	/** 4字节协议头 **/
	int NewP2PProtocolHead(char * _head,int nP2c,int nDataLen,int nSign,int nOffset,Bit16 serial);
	/** 获取协议头 nP2c值 **/
	int GetHeadnP2c(char * _head);
	/** 获取nDataLen值 **/
	int GetHeadnDataLen(char * _head);
	/** 获取协议头 nSign值 **/
	int GetHeadnSign(char * _head);
	/** 获取nOffset值 **/
	int GetHeadnOffset(char * _head);
	/** 获取校验和 **/
	int GetHeadCkSum(Bit16 *_ckSum,char * _head);
	/** 获取数据序号 **/
	int GetHeadSerial(Bit16 *_ckSum,char * _head);

	int GetUserAgentLocalIP(void);
	int LutRandom(int ran,int tm);
	Bit16 LutCkSum(Bit8* buffer, int size);
	Bit16 GetDataSerial(void);
	int GetNativeDeviceCode(Bit8 * szUserAgent,int * nUserAgentLen);
	int NewLutSacSYNPackage(LutPackage_t *_LutPackage);
	int CompareArray(unsigned char *szBytes1,unsigned char *szBytes2,int offset,int limit);

	void AES_Encrypt_Len(unsigned int plainTextLen,unsigned int *cliperTextLen);
	/** 协议专用转发 **/
	void *iportPipe_proto(void *spipe);
#define FreeLutProtocol(psk,pskda)			  \
	do{										  \
		if(psk){							  \
			if(psk->pskda){					  \
				free(psk->pskda);			  \
				psk->pskda = NULL;			  \
			}								  \
			free(psk);						  \
			psk = NULL;						  \
		}									  \
	}while(0)
	
#define BytePrintDebug 0
#define PrintLutByte(ti,data,len)			 \
	do{										 \
		if(BytePrintDebug){                  \
			int i = 0;						 \
			printf("%s ：",ti);				 \
			for(i = 0;i<len;i++){			 \
				printf("%02X ",data[i]);	 \
			}								 \
			printf("\n");					 \
		}									 \
	}while(0)
#ifndef _LOG_DEBUG
#define LOG_DEBUG(format,...)  
#else  
#define LOG_DEBUG(format,...) printf("PRINT| "__FILE__"| %05d| "format"", __LINE__, ##__VA_ARGS__)  
#endif  

#ifdef __cplusplus
}
#endif
#endif
